<?php
/**
 * 余额提现
 * author universe.h
 */
namespace Api\Controller;

use Common\Controller\InterceptController;
use Common\Lib\Wxpay\Wxpay;
use Common\Controller\AdvController;

class WithdrawalsController extends InterceptController
{
    /**
     * 提现
     * time 2017.10.30
     */
    public function cash()
    {
        $wdStatus      = C('WITHDRAWAL_STATUS');
        if (!$wdStatus) {
            $this->ajaxReturn(['code' => 50000, 'msg' => '人数较多请稍后再提现']);
        }
        if(isset($this->user_info['status']) && $this->user_info['status'] == 1){
            $this->ajaxReturn(['code' => 40000, 'msg' => '账号已被禁用']);
        }
        //业务开始
        $amount       = I('post.amount/f');
        $wd_model     = M('Withdrawals');
        $profit_model = M('ProfitLog');
        $user_model   = M("WxUser");
        $info         = $user_model->where(['id' => $this->user_id])->find();
        //配置信息
        $ratio               = C('WITHDRAWAL_RATIO') / 100;//佣金费率
        $minWithdrawals      = C('MIN_WITHDRAWALS');
        $max_withdrawal_time = C('MAX_WITHDRAWAL_TIME');
        //提现次数
        $cacheTimeKey = 'WithdrawalsControllerCashTime'.date('Y-m-d').$this->user_id;
        $cacheTime = S($cacheTimeKey);
        if ($cacheTime >= $max_withdrawal_time) {
            $this->ajaxReturn(['code' => 50000, 'msg' => '每天最多' . $max_withdrawal_time . '次']);
        }

        $cash_amount = sprintf("%.2f", $info['amount'] - $info['frozen_amount']);

        if ($amount < $minWithdrawals) {
            $this->ajaxReturn(['code' => 50000, 'msg' => '提现最低' . $minWithdrawals . '元']);
        }

        if ($amount > $cash_amount) {
            $this->ajaxReturn(['code' => 50000, 'msg' => '不能大于余额']);
        }

        $updateMoney = sprintf("%.2f", $cash_amount - $amount);
        $true_amount = number_format($amount - $ratio * $amount,2);
        if ($true_amount < 1) {
            $this->ajaxReturn(['code' => 50000, 'msg' => '不能低于1元']);
        }
        //并发控制，锁机制
        $cacheKey = 'WithdrawalsControllerCash';
        $cache = S($cacheKey);
        if($cache > 10){
            $this->ajaxReturn(['code' => 50000, 'msg' => '人数较多请稍后再提现。']);
        }
        //记录任务
        $cache = S($cacheKey);
        S($cacheKey, $cache+1, ['expire' => 30]);

        //事务开始
        M()->startTrans();
        $res_user = $user_model->where(['id' => $this->user_id])->setDec('amount', $amount);

        if (!$res_user) {
            $user_model->rollback();
            $this->ajaxReturn(['code' => 20400, 'msg' => '人数较多请稍后再提现.']);
        }
        //记录日志
        $log_data = [
            'user_id'     => $this->user_id,
            'amount'      => $amount,
            'openid'      => $this->openid,
            'pay_desc'    => '余额提现',
            'add_time'    => time(),
            'true_amount' => $true_amount,
        ];
        $wd_id    = $wd_model->add($log_data);
        if (!$wd_id) {
            $wd_model->rollback();
            $this->ajaxReturn(['code' => 20400, 'msg' => '人数较多请稍后再提现.']);
        }
        //佣金记录
        $profit_data = [
            'wd_id'      => $wd_id,
            'user_id'    => $this->user_id,
            'ratio'      => $ratio,
            'amount'     => number_format($amount-$true_amount,2),
            'ori_amount' => $amount,
            'openid'     => $this->openid,
            'desc'       => '余额提现佣金',
            'nick_name'  => $this->user_info['nick_name'],
            'head_img'   => $this->user_info['head_img'],
            'source'     => __ACTION__,
            'add_time'   => time(),
        ];
        $ret         = $profit_model->add($profit_data);
        if (!$ret) {
            $profit_model->rollback();

            $this->ajaxReturn(['code' => 20400, 'msg' => '人数较多请稍后再提现.']);
        }
        //支付
        $data = [
            'openid'           => $this->openid,
            'partner_trade_no' => create_order($wd_model, 'partner_trade_no', C('CASH_FIX')),
            're_user_name'     => '',
            'amount'           => bcmul($true_amount, 100),
            'desc'             => '用户余额提现',
        ];

        $wx  = new Wxpay();
        $res = $wx->transfers($data);
        if ($res['result_code'] != 'SUCCESS') {
            $user_model->rollback();
            //失败记录日志
            $err_code_des = isset($res['err_code_des']) ? $res['err_code_des'] : '';
            $log_data = [
                'user_id'     => $this->user_id,
                'amount'      => $amount,
                'openid'      => $this->openid,
                'pay_desc'    => '余额提现失败-'.$err_code_des,
                'add_time'    => time(),
                'true_amount' => $true_amount,
                'status' => 'FAIL',
                'err_code_des' => json_encode($res),
            ];
            $wd_model->add($log_data);
            $msg = '人数较多请稍后再提现！';
            if(isset($res['err_code']) && $res['err_code'] == 'V2_ACCOUNT_SIMPLE_BAN'){
                $msg = '非实名账号';
                //记录提现次数
                $cacheTime = S($cacheTimeKey);
                S($cacheTimeKey, $cacheTime+1, ['expire' => 86400]);
            }
            $this->ajaxReturn(['code' => 20400, 'msg' => $msg]);
        }

        //提交事务
        M()->commit();
        //更新记录日志
        $log_data = [
            'appid'            => $res['mch_appid'],
            'openid'           => $res['openid'],
            'check_name'       => $res['check_name'],
            're_user_name'     => $res['re_user_name'],
            'id_card'          => $res['id_card'] ?? '',
            'pay_desc'         => '余额提现',
            'err_code_des'     => $res['err_code_des'] ?? '',
            'nonce_str'        => $res['nonce_str'],
            'partner_trade_no' => $res['partner_trade_no'],
            'spbill_create_ip' => $res['spbill_create_ip'],
            'status'           => $res['result_code'],
            'true_amount'      => number_format($res['amount'] / 100,2),
        ];
        $wd_model->where(['id' => $wd_id])->save($log_data);
        //释放缓存
        $cache = S($cacheKey);
        S($cacheKey, $cache-1, ['expire' => 30]);
        //记录提现次数
        $cacheTime = S($cacheTimeKey);
        S($cacheTimeKey, $cacheTime+1, ['expire' => 86400]);

        $this->ajaxReturn(['code' => 20000, 'msg' => 'success', 'data' => $info]);
    }

    /*
     * 余额和广告接口
     */
    public function amountAndAdv()
    {
        $info           = M("WxUser")->field(['amount', 'frozen_amount'])->where(['id' => $this->user_id])->find();
        $cash           = number_format($info['amount'] - $info['frozen_amount'], 2);
        $cash           = $cash < 0 ? '0.00' : $cash;
        $adv            = null;//AdvController::instance()->getAdv('cquestion');
        $withdrawaltime = 0;
        $this->ajaxReturn(['code' => 20000, 'msg' => 'success', 'amount' => $cash, 'adv' => $adv,'withdrawal_ratio' => C('WITHDRAWAL_RATIO')/100,  'min_withdrawals' => C('MIN_WITHDRAWALS'), 'max_withdrawal_time' => C('MAX_WITHDRAWAL_TIME'), 'withdrawal_time' => C('MAX_WITHDRAWAL_TIME') - $withdrawaltime]);
    }
}

